package com.mryan.chat.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mryan.chat.pojo.User;
import com.mryan.chat.util.Json;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * @description： 实现WebSocket传输功能
 * @Author MRyan
 * @Date 2020/12/26 10:10
 * @Version 1.0
 */
@ServerEndpoint("/chat/{uid}")
@Controller
public class MyWebSocket implements Json {

    private static final Logger logger = Logger.getLogger(String.valueOf(MyWebSocket.class));

    /**
     * 存放所有用户session（当前在线用户）
     */
    private static Map<String, Session> sessions = new ConcurrentHashMap<>();

    //随机头像存储源
    String[] head_images = new String[]{"christian.jpg",
            "daniel.jpg",
            "elliot.jpg",
            "helen.jpg",
            "jenny.jpg",
            "lena.png",
            "lindsay.png",
            "mark.png",
            "matt.jpg",
            "molly.png",
            "steve.jpg",
            "stevie.jpg",
            "tom.jpg",
            "veronika.jpg"};


    @OnOpen
    public void onOpen(Session session, @PathParam("uid") String uid) throws IOException {
        if (sessions.containsKey(uid)) {
            logger.info("用户已存在");
            Map<String, String> map = new HashMap<>();
            map.put("type", "err_user_exist");
            session.getBasicRemote().sendText(toJson(map));
            return;
        }
        logger.info("用户已登录：" + uid);
        String header = head_images[new Random().nextInt(head_images.length)];
        User user = new User(header, uid);
        session.getUserProperties().put("user", user);
        sessions.put(uid, session);
        freshUsers();
    }

    /**
     * 刷新列表
     */
    public void freshUsers() throws IOException {
        List<Object> userslist = sessions.values().stream().map(user -> user.getUserProperties().get("user")).collect(Collectors.toList());
        Map<String, Object> messages = new HashMap<>();
        messages.put("type", "update_user");
        messages.put("users", userslist);
        String msg = toJson(messages);
        for (Session session : sessions.values()) {
            session.getBasicRemote().sendText(msg);
        }
    }


    @OnClose
    public void onClose(Session session) throws IOException {
        User user = (User) session.getUserProperties().get("user");
        sessions.remove(user.getName());
        freshUsers();
    }


    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }


    @OnMessage
    public void onMessage(Session session, String msg) throws IOException {
        Map<String, Object> message = new HashMap<>();
        //图片消息
        if (msg.startsWith("$img")) {
            message.put("type", "img_msg");
            message.put("msg", msg.substring(4));
        } else {
            //普通消息
            message.put("type", "normal_msg");
            message.put("msg", msg);
        }
        message.put("user", session.getUserProperties().get("user"));
        // 接收消息
        for (Session s : sessions.values()) {
            s.getBasicRemote().sendText(toJson(message));
        }
    }

    /***
     *  将传回前端消息转换为json格式
     * @param map
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public String toJson(Map<String, ?> map) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(map);
    }
}
